package controllers

import (
	"goravel/app/models"
	"goravel/app/scopes"
	"goravel/utils/response"
	"strconv"

	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/facades"
)

type PermissionsController struct {
	// Dependent services
	BaseController
}

func NewPermissionsController() *PermissionsController {
	return &PermissionsController{
		// Inject services
	}
}

func (c *PermissionsController) Index(ctx http.Context) http.Response {
	var permissions []models.Permission
	var total int64

	page, perPage := c.GetPaginationParams(ctx)

	query := scopes.Query(ctx)

	// 打印生成的SQL
	// sqlInfo := query.ToSql()
	// fmt.Println(sqlInfo)

	query = query.OrderBy("sort", "asc")

	if err := query.Paginate(page, perPage, &permissions, &total); err != nil {
		return response.Fail(ctx, http.StatusInternalServerError, facades.Lang(ctx).Get("errors.failed_to_fetch"))
	}

	return response.Paginate(ctx, permissions, total, page, perPage)
}

// AssignPermissionsToRole POST /permissions/assign-to-role
func (c *PermissionsController) AssignPermissionsToRole(ctx http.Context) http.Response {
	validator, err := ctx.Request().Validate(map[string]string{
		"role_id":        "required|integer",
		"permission_ids": "required|array",
	})

	if err != nil {
		return response.Fail(ctx, http.StatusBadRequest, "Validation failed: "+err.Error())
	}

	if validator.Fails() {
		return response.Fail(ctx, http.StatusBadRequest, validator.Errors().One())
	}

	roleID := ctx.Request().InputInt("role_id")
	permissionIDs := ctx.Request().InputArray("permission_ids")

	// 检查角色是否存在
	var role models.Role
	if err := facades.Orm().Query().FindOrFail(&role, roleID); err != nil {
		return response.Fail(ctx, http.StatusNotFound, "角色不存在")
	}

	// 开始事务
	tx, err := facades.Orm().Query().Begin()
	if err != nil {
		return response.Fail(ctx, http.StatusInternalServerError, "开始事务失败")
	}

	// 删除该角色的所有权限
	if _, err := tx.Model(&models.RolePermission{}).Where("role_id", roleID).Delete(&models.RolePermission{}); err != nil {
		tx.Rollback()
		return response.Fail(ctx, http.StatusInternalServerError, "删除角色权限失败")
	}

	// 分配新权限
	for _, permID := range permissionIDs {
		// 将字符串转换为整数
		permIDInt, err := strconv.Atoi(permID)
		if err != nil {
			tx.Rollback()
			return response.Fail(ctx, http.StatusBadRequest, "权限ID格式错误")
		}

		rolePermission := models.RolePermission{
			RoleId:       uint(roleID),
			PermissionId: uint(permIDInt),
		}

		if err := tx.Create(&rolePermission); err != nil {
			tx.Rollback()
			return response.Fail(ctx, http.StatusInternalServerError, "分配权限失败")
		}
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return response.Fail(ctx, http.StatusInternalServerError, "提交事务失败")
	}

	return response.Success(ctx, http.Json{
		"message": "权限分配成功",
		"role_id": roleID,
	})
}

// AssignRolesToUser POST /permissions/assign-roles-to-user
func (c *PermissionsController) AssignRolesToUser(ctx http.Context) http.Response {
	validator, err := ctx.Request().Validate(map[string]string{
		"user_id":  "required|integer",
		"role_ids": "required|array",
	})

	if err != nil {
		return response.Fail(ctx, http.StatusBadRequest, "Validation failed: "+err.Error())
	}

	if validator.Fails() {
		return response.Fail(ctx, http.StatusBadRequest, validator.Errors().One())
	}

	userID := ctx.Request().InputInt("user_id")
	roleIDs := ctx.Request().InputArray("role_ids")

	// 检查用户是否存在
	var user models.User
	if err := facades.Orm().Query().FindOrFail(&user, userID); err != nil {
		return response.Fail(ctx, http.StatusNotFound, "用户不存在")
	}

	// 开始事务
	tx, err := facades.Orm().Query().Begin()
	if err != nil {
		return response.Fail(ctx, http.StatusInternalServerError, "开始事务失败")
	}

	// 删除该用户的所有角色
	if _, err := tx.Model(&models.UserRole{}).Where("user_id", userID).Delete(&models.UserRole{}); err != nil {
		tx.Rollback()
		return response.Fail(ctx, http.StatusInternalServerError, "删除用户角色失败")
	}

	// 分配新角色
	for _, roleID := range roleIDs {
		// 将字符串转换为整数
		roleIDInt, err := strconv.Atoi(roleID)
		if err != nil {
			tx.Rollback()
			return response.Fail(ctx, http.StatusBadRequest, "角色ID格式错误")
		}

		userRole := models.UserRole{
			UserId: uint(userID),
			RoleId: uint(roleIDInt),
		}

		if err := tx.Create(&userRole); err != nil {
			tx.Rollback()
			return response.Fail(ctx, http.StatusInternalServerError, "分配角色失败")
		}
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return response.Fail(ctx, http.StatusInternalServerError, "提交事务失败")
	}

	return response.Success(ctx, http.Json{
		"message": "角色分配成功",
		"user_id": userID,
	})
}
